﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))]
public class SmoothPathCurveMesh : SmoothPathCurve
{
    private Mesh mesh;
    private Vector2[] uvs;
    private Vector3[] vertexs;

    [SerializeField]
    private AnimationCurve curveWidthLength = new AnimationCurve(new Keyframe(0, 1), new Keyframe(1, 1));

    [SerializeField]
    Vector2 curveRandomRadio = Vector2.zero;

    [Range(0f, 5)]
    [SerializeField]
    float curveOffsetY = 0f;

    /// <summary>
    /// 边缘波峰高度
    /// </summary>
    [SerializeField]
    [Range(0, 2)]
    float curveRandomWaveHight = 0f;


#if UNITY_EDITOR
    protected override void OnValidate()
    {
        base.OnValidate();
    }

#endif

    /// <summary>
    /// 重置按键，Mono脚本自动加载，editor下使用
    /// </summary>

    protected override void Reset()
    {
        base.Reset();
        this.m_Appearance.width = 1;
        curveOffsetY = 0;
        curveRandomRadio = Vector2.zero;
        curveRandomWaveHight = 0;

        CreateCurvePathPoint();
        CreatMeshCurve();
    }
    public override void UpdatePoint(int index, Vector3 pos)
    {
        if (index < m_Waypoints.Length) m_Waypoints[index].position = pos;
        CreateCurve();
    }
    public void CreateCurve()
    {
        CreateCurvePathPoint();
        CreatMeshCurve();
    }

    private void CreateCurvePathPoint()
    { 
        int count = 0;
        float step = 1f / m_Resolution;
        float tEnd = MaxPos + step / 2;
        for (float t = MinPos; t <= tEnd; t += step)
        {
            count++;
        }

        vertexs = new Vector3[count * 2];
        uvs = new Vector2[count * 2];
    }


    private void CreatMeshCurve()
    {
        if (mesh == null) GetComponent<MeshFilter>().mesh = mesh = new Mesh();
        mesh.name = "Curve Mesh";
        DrawMesh();
    }

    /// <summary>
    /// 绘制Mesh
    /// </summary>
    public void DrawMesh()
    {
        CalcuterVertices();
        mesh.Clear();
        mesh.vertices = vertexs;
        mesh.triangles = getTriangles(mesh.vertexCount);
        mesh.uv = uvs;
        mesh.RecalculateNormals();
    }

    /// <summary>
    /// 顶点计算
    /// </summary>
    /// <returns></returns>
    void CalcuterVertices()
    {
        int index = 0;
        float width = this.m_Appearance.width;
        //下沉量
        Vector3 _offsetY = curveOffsetY * Vector3.down;

        float step = 1f / this.m_Resolution;
        Vector3 lastPos = this.EvaluatePosition(this.MinPos);

        float tEnd = this.MaxPos + step / 2;
        for (float t = this.MinPos; t <= tEnd; t += step, index++)
        {
            Vector3 p = this.EvaluateLocalPosition(t);
            Quaternion q = this.EvaluateOrientation(t);//控制点旋转角度
            Vector3 worldPos = this.EvaluatePosition(t);
            //随机波峰宽度
            float halfWidth = (width *
            (1 + curveRandomWaveHight *
            (Mathf.PerlinNoise(worldPos.x * curveRandomRadio.x, worldPos.z * curveRandomRadio.y)))) * 0.5f;
          
            float _lengthPercents = (float)index / vertexs.Length;
            halfWidth *= curveWidthLength.Evaluate(_lengthPercents);

            Vector3 w = (q * Vector3.right) * halfWidth * width;
            Vector3 p0 = p - w + _offsetY;
            Vector3 p1 = p + w + _offsetY;

            //右顶点
            vertexs[index * 2] = p1 ;
            //左顶点
            vertexs[index * 2 + 1] = p0; 

            //v
            uvs[2 * index].y = uvs[2 * index + 1].y = (float)index / (vertexs.Length / 2 - 1) * PathLength;
            //u
            uvs[2 * index].x = 0;
            uvs[2 * index + 1].x = 1;
        }

    }

    

    /// <summary>
    /// 三角面计算
    /// </summary>
    /// <param name="count"></param>
    /// <returns></returns>
    int[] getTriangles(int count)
    {
        List<int> vector3s = new List<int>();
        for (int i = 0; i < count - 2; i += 2)
        {
            //右下三角面
            int p0, p1, p2;
            p0 = i;
            p1 = i + 1;
            p2 = i + 2;
            vector3s.Add(p0);
            vector3s.Add(p1);
            vector3s.Add(p2);

            //左上三角面
            p0 = i + 1;
            p1 = i + 3;
            p2 = i + 2;
            vector3s.Add(p0);
            vector3s.Add(p1);
            vector3s.Add(p2);
        }

        return vector3s.ToArray();
    }

}
